RSMS VM — worker as a Windows service (NSSM)
Environment: Production RSMS VM (Windows Server). The simulation worker runs as a Windows service wrapped by NSSM (Non-Sucking Service Manager), not Azure Functions.
Related: rsms-worker-implementation-plan (queue worker design), rsms-worker-ohio-riverflows-tls (Python TLS / certifi on this host).
Overview
The worker entrypoint is queue_worker.py: it polls Azure Storage Queue and runs the RSMS pipeline for each message. On RSMS VM we keep that process running under NSSM so it survives logoff, restarts on failure, and can start at boot.
Why NSSM
- Straightforward wrapper for a long-running console process (here:
python.exe+ script). - Optional automatic restart if the process exits.
- Configure via CLI or GUI; no custom C# Windows service project.
- Works well with a per-VM Python virtual environment (explicit path to
Scripts\python.exe).
Example paths (RSMS VM)
Adjust user name, drive, and clone location if your VM differs.
| Role | Example path |
|---|---|
| Python (venv) | C:\Users\gqc\Envs\rsms\Scripts\python.exe |
| Worker repo root | C:\RSMS\rsms-worker-function |
| Worker script | C:\RSMS\rsms-worker-function\queue_worker.py |
| Working directory | C:\RSMS\rsms-worker-function (so imports, .env, and relative paths match manual runs) |
| Logs | C:\RSMS\logs\ (create the folder before pointing NSSM at it) |
Ensure local.settings.json, .env, or system/user environment variables supply AZURE_STORAGE_CONNECTION_STRING, RSMS_WORKER_QUEUE_NAME, EXE_DIR, and the rest per rsms-worker-function/README.md.
Install and configure NSSM (CLI)
Install NSSM and ensure
nssm.exeis onPATH(or invoke it with a full path).Create the service (opens a GUI on some versions; the
setcommands below apply either way):nssm install RSMSWorkerPoint the service at the venv Python and the queue worker:
nssm set RSMSWorker Application "C:\Users\gqc\Envs\rsms\Scripts\python.exe"
nssm set RSMSWorker AppParameters "queue_worker.py"
nssm set RSMSWorker AppDirectory "C:\RSMS\rsms-worker-function"Logging (stdout/stderr files):
nssm set RSMSWorker AppStdout "C:\RSMS\logs\worker-out.log"
nssm set RSMSWorker AppStderr "C:\RSMS\logs\worker-err.log"Optional size-based rotation (NSSM only; not a substitute for structured app logging):
nssm set RSMSWorker AppRotateFiles 1
nssm set RSMSWorker AppRotateOnline 1
nssm set RSMSWorker AppRotateBytes 10485760Prefer
LOG_LEVELand Python logging configuration for retention and fields you care about in production.Start the service:
nssm start RSMSWorker
Use nssm edit RSMSWorker for a GUI review of all options (restart delay, exit action, etc.).
Start automatically at boot
PowerShell:
Set-Service -Name RSMSWorker -StartupType Automatic
Alternative (sc.exe, not the sc alias):
sc.exe config RSMSWorker start= auto
The space after start= is required.
Verification
Service configuration:
sc.exe qc RSMSWorker
Expect START_TYPE AUTO_START (value 2) when configured for automatic start.
Runtime:
- Tail
C:\RSMS\logs\worker-out.logandworker-err.log. - Confirm messages are consumed from the configured queue after the API returns 202 for a run.
Summary
| Capability | NSSM + queue_worker.py |
|---|---|
| Always-on worker | Yes — service runs until stopped |
| Restart on crash | Configure in NSSM (e.g. restart application on exit) |
| Boot persistence | Automatic startup type |
| Logs | NSSM stdout/stderr files; add app-level logging as needed |
Typical next improvements: structured logging with rotation, monitoring/alerting on queue depth and process health, and (if needed) multiple worker instances or VMs for throughput.